<template>
  <div :style="style">
    <el-table
      class="sys-tabel"
      ref="charttable"
      :header-row-style="{'color': color}"
      :style="{'color': color}"
      v-if="chartType === 'table'"
      :data="tablelist"
      :height="parseInt(style.height)"
    >
      <el-table-column
        v-for="(column,index) in columns"
        :min-width="index < 4 ? '19%': '41%'"
        :key="column.field_name"
        :prop="column.field_name"
        :label="column.show_name"
      ></el-table-column>
    </el-table>
    <div
      :style="wordInfo.css"
      v-else-if="chartType === 'word' && wordInfo.word.indexOf('YYYY') > -1"
    >{{now | dateformat(dataFormatPattern)}}</div>
    <div
      :style="wordInfo.css"
      v-else-if="chartType === 'word' && wordInfo.word.indexOf('天气') > -1"
      v-html="weather"
    ></div>
    <svg :width="parseInt(style.width)" :height="parseInt(style.height)" 
      v-else-if="chartType === 'hots'"
    >
      <a v-for='(tag, index) in hots.tags' :key="tag.name">
        <text :x='tag.x' :y='tag.y' :font-size='tag.size' :fill="hots.colors[index%5]" :fill-opacity='((400+tag.z)/600)'>{{tag.text}}</text>
      </a>
    </svg>
    <div :style="wordInfo.css" v-else-if="chartType === 'word'" class="wordediter">{{wordInfo.word}}</div>
    <div
      v-else
      :id="id"
      :style="{'width': parseInt(style.width) + 'px', 'height': parseInt(style.height) + 'px', 'border': style.border ? '1px solid ' + style.border : 'none' }"
    ></div>
  </div>
</template>
<script>
import echarts from "echarts";
import { mapMutations } from "vuex";
import Services from "@/services";
import moment from "moment";
import { setTimeout, setInterval } from "timers";
import citys from '@/assets/weather_city.json'
export default {
  data() {
    return {
      echart: null,
      chartType: "chart",
      tablelist: [],
      columns: [],
      dataFormatPattern: "",
      now: moment(),
      top: 0,
      height: 0,
      wapper: null,
      table: null,
      weather: '',
      hots: {
        RADIUS: 0,
        speedX: Math.PI / 360,
        speedY: Math.PI / 360,
        colors: ["#e86e6e", "#c8b566", "#6ee8bf", "#7e6654", "#6eafe8"],
        tags: [],
        playtime: 0,
        playtimeout: null
      }
    };
  },
  props: {
    component: Object,
    scale: Number,
    grid: Number,
    bsId: Number,
    color: String
  },
  filters: {
    dateformat(dataStr, pattern) {
      return moment(dataStr).format(pattern);
    }
  },
  computed: {
    // time(){
    //   var wordInfo = JSON.parse(this.component.bsChartInfo.wordInfo)
    //   return moment().format(wordInfo.word)
    // },
    wordInfo() {
      var wordInfo = JSON.parse(this.component.bsChartInfo.wordInfo);
      if (wordInfo.css.fontSize) {
        wordInfo.css.fontSize = wordInfo.css.fontSize;
      }
      return wordInfo;
    },
    id() {
      return "echart" + this.component.bsChartInfo.id;
    },
    grids() {
      return [this.grid, this.grid];
    },
    style() {
      try {
        let chartConfig = JSON.parse(
          this.component.bsChartComponent.chartConfig
        );
        return {
          position: "absolute",
          width: this.component.bsChartInfo.width + "px",
          height: this.component.bsChartInfo.height + "px",
          left: this.component.bsChartInfo.x + "px",
          top: this.component.bsChartInfo.y + "px",
          border:
            chartConfig.style && chartConfig.style.border
              ? chartConfig.style.border
              : null
        };
      } catch (error) {
        return {
          position: "absolute",
          width: this.component.bsChartInfo.width + "px",
          height: this.component.bsChartInfo.height + "px",
          left: this.component.bsChartInfo.x + "px",
          top: this.component.bsChartInfo.y + "px"
        };
      }
    },
    CX() {
      try {
        let chartConfig = JSON.parse(
          this.component.bsChartComponent.chartConfig
        );
        return this.component.bsChartInfo.width / 2;
      } catch (error) {
        return 0;
      }
    },
    CY() {
      try {
        let chartConfig = JSON.parse(
          this.component.bsChartComponent.chartConfig
        );
        return this.component.bsChartInfo.height / 2;
      } catch (error) {
        return 0;
      }
    }
  },
  mounted() {
    moment.locale("zh-cn");
    var wordInfo = this.component.bsChartInfo.wordInfo
      ? JSON.parse(this.component.bsChartInfo.wordInfo)
      : "";
    if (wordInfo.word && wordInfo.word.indexOf("YYYY") > -1) {
      //  如果是日期 定时更新
      this.dataFormatPattern = wordInfo.word;
      const vm = this;
      setInterval(() => {
        vm.now = moment();
      }, 1000);
    }
    if (this.component.bsChartComponent.chartType == 1) {
      // 表格类型
      this.chartType = "table";
      Services.CHARTS_OPTION({
        componentId: this.component.bsChartInfo.componentId,
        title: this.component.bsChartInfo.name,
        bsId: this.bsId
      }).then(res => {
        this.columns = res.dataMapping;
        this.tablelist = res.dataValue;
        this.$nextTick(function() {
          this.initRoll();
        });
      });
    } else if (this.component.bsChartComponent.chartType == 20) {
      // 文字类型
      this.chartType = "word";
      // this.wordjson = JSON.parse(this.component.bsChartInfo.wordInfo)
      if(wordInfo.word.indexOf('天气') > -1){
          let city = wordInfo.word
          city = city.replace('天气', '')
          let citycode = !1
          for(let i = 0 ; i < citys.length ; i ++){
            if(citys[i].city_name == city){
              citycode = citys[i].city_code
            }
          }
          if(citycode){
            Services.WEATHER({
              cityCode: citycode
            }).then(res => {
              console.log(res)
              var todayWeather = res.data.forecast[0]
              var low = todayWeather.low.replace('低温 ', '')
              var high = todayWeather.high.replace('高温 ', '')
              this.weather =  todayWeather.type + '&nbsp;&nbsp;' + low + '~' + high + '&nbsp;&nbsp;' + todayWeather.fx + todayWeather.fl
              console.log(this.weather)
              
            })
          }
        }
    } else {
      this.chartType = "chart";
      Services.CHARTS_OPTION({
        // 获取图标echarts options
        componentId: this.component.bsChartInfo.componentId,
        title: this.component.bsChartInfo.name,
        bsId: this.bsId
      })
        .then(res => {
          this.echart = echarts.init(document.getElementById(this.id));
          const vm = this;
          var chartConfig = JSON.parse(
            this.component.bsChartComponent.chartConfig
          )
          if (this.component.bsChartComponent.chartType == 7) {
            // 如果是地图
            let mapdata = [];
            
            let mapjson = chartConfig.adcode;
            let map = require("@/assets/map/" + mapjson + "_full.json"); // 注册和加载地图
            echarts.registerMap("MAPS", map);
            map.features.forEach((geo, index) => {
              mapdata.push({
                name: geo.properties.name,
                value: 0
              });
            });
            let options = res;
            Services.CHARTS_MAP().then(ws => {
              // 获取websock数据 针对盐城的大屏
              if (ws.length > 0) {
                let min = 0,
                  max = 0;
                ws.forEach(city => {
                  let name = Object.keys(city)[0];
                  let val = +Object.values(city)[0];
                  if (min > val || min == 0) min = val;
                  if (val > max) max = val;
                  mapdata.forEach((map, index) => {
                    if (map.name.indexOf(name) > -1) {
                      map.value = val;
                    }
                  });
                });
                options.visualMap = {
                  show: false,
                  min: +min,
                  max: +max,
                  left: "left",
                  top: "bottom",
                  text: ["High", "Low"],
                  seriesIndex: [0],
                  inRange: {
                    color: ["#084c7e", "#1bc75c"]
                  },
                  calculable: true
                };
              }
              options.series.unshift({
                name: "categoryA",
                type: "map",
                geoIndex: 0,
                data: mapdata
              });
              options.tooltip.formatter = "{b0}：{c0}";
              options.geo.zoom = 1;
              options.geo.scaleLimit = { min: 1, max: 3 };
              options.geo.roam = true;
              this.echart.setOption(options);
              
              if(chartConfig.iscarousel){ // 轮播开关
                var index = 0; 
                var mTime = setInterval(function() {
                  vm.echart.dispatchAction({
                    type: "showTip",
                    seriesIndex: 0,
                    dataIndex: index
                  });
                  index++;
                  if (index > mapdata.length) {
                    index = 0;
                  }
                }, 2500);
              }
            });
          } else {
            if (this.component.bsChartInfo.width < 300) {
              res.title.textStyle.fontSize = 12;
              res.legend.textStyle.fontSize = 12;
              res.legend.itemWidth = 8;
              res.legend.itemHeight = 8;
              res.legend.itemGap = 8;
              res.series.forEach(series => {
                series.label.emphasis.textStyle.fontSize = 12
                return series
              })
            }
            if (this.component.bsChartComponent.chartType == 2 || this.component.bsChartComponent.chartType == 10) {   // 柱 宽度 和 文字
              res.series.forEach(series => {
                series.barWidth = chartConfig.barWidth
                ? chartConfig.barWidth
                : "auto";
                if(this.component.bsChartComponent.chartType == 2){
                  series.label = {
                    normal: {
                      show: true,
                      position: 'top'
                    }
                  }
                }
                
                return series
              })
            }
            if(this.component.bsChartComponent.chartType == 3) {    // 折线  渐变
              res.series.forEach(series => series = this.setAreaStyle(series))
            }
            if(this.component.bsChartComponent.chartType == 4 || this.component.bsChartComponent.chartType == 5 ) {
              var index = 0; 
              var mTime = setInterval(function() {
                vm.echart.dispatchAction({
                  type: "highlight",
                  seriesIndex: 0,
                  dataIndex: index
                })
                vm.echart.dispatchAction({
                  type: "showTip",
                  seriesIndex: 0,
                  dataIndex: index
                })
                vm.echart.dispatchAction({
                  type: "downplay",
                  seriesIndex: 0,
                  dataIndex: index-1
                })
                index++;
                if (index > res.series[0].data.length - 1) {
                  index = 0;
                }
              }, 2500);
            }
            if(this.component.bsChartComponent.chartType == 10 || this.component.bsChartComponent.chartType == 11) {
                const CbarChartConfig = JSON.parse(this.component.bsChartComponent.chartConfig)
                if(CbarChartConfig.style && typeof(CbarChartConfig.style.color) != "undefined") {
                  res.color = CbarChartConfig.style.color
                }
            }
            if(this.component.bsChartComponent.chartType == 12) {
              this.chartType = 'hots'
              // 如果是热词
              this.hots.tags = res.data
              this.startRotate()
            } else {
              this.echart.setOption(res);
            }
            if (this.component.bsChartComponent.isDrill == 1) {
              this.echart.on("click", function(params) {
                vm.handlerDrill(params, vm.component.bsChartComponent);
              });
            }
          }
        })
        .catch(error => {
          document.getElementById(this.id).innerHTML =
            '<div style="font-size:18px;color:#ff0000;text-align:center;margin-top:20px;">数据源获取数据失败。</div>';
        });
    }
  },
  methods: {
    handlerDrill(params, component) {
      console.log(component);
      const drillParams = JSON.parse(component.drillParams);
      const drillKey = Object.keys(drillParams)[0];
      const drillValue = Object.values(drillParams)[0];
      const chartConfig = JSON.parse(component.chartConfig);
      let payload = "";
      switch (component.chartType) {
        case 2:
          let bx = chartConfig.x;
          let by1 = chartConfig.y[0].name;
          let by2 = chartConfig.y[1] ? chartConfig.y[0].name : null;
          if (drillKey == bx) {
            payload = drillValue + "='" + params.name + "'";
          }
          if (drillKey == by1 || drillKey == by2) {
            payload = drillValue + "='" + params.data + "'";
          }
          break;
        case 3:
          let lx = chartConfig.x;
          let ly1 = chartConfig.y[0].name;
          let ly2 = chartConfig.y[1] ? chartConfig.y[0].name : null;
          if (drillKey == lx) {
            payload = drillValue + "='" + params.name + "'";
          }
          if (drillKey == ly1 || drillKey == ly2) {
            payload = drillValue + "='" + params.data + "'";
          }
          break;
        case 4:
          let cname = chartConfig.name;
          let cvalue = chartConfig.value;
          if (drillKey == cname) {
            payload = drillValue + "='" + params.data.name + "'";
          }
          if (drillKey == cvalue) {
            payload = drillValue + "='" + params.data.value + "'";
          }
          break;
        case 5:
          let pname = chartConfig.name;
          let pvalue = chartConfig.value;
          if (drillKey == pname) {
            payload = drillValue + "='" + params.data.name + "'";
          }
          if (drillKey == pvalue) {
            payload = drillValue + "='" + params.data.value + "'";
          }
          break;
      }
      this.$emit("showDrillTable", component.drillChartId, payload);
      // this.showDrillTable()
    },
    initRoll() {
      let wapper = this.$refs.charttable.$el.children[2];
      let tabelHTML = wapper.innerHTML;
      wapper.innerHTML = tabelHTML + tabelHTML;
      this.wapper = wapper;
      this.table = wapper.children[0];
      this.height = this.table.offsetHeight;
      // console.log
      this.tableAutoRoll(wapper);
    },
    tableAutoRoll() {
      this.wapper.scrollTop = this.top;
      if (this.top < this.height) {
        this.top++;
      } else {
        this.top = 0;
        this.wapper.scrollTop = 0;
      }
      const vm = this;
      setTimeout(vm.tableAutoRoll, 50);
    },
    setAreaStyle(series){
      let color = series.color
      if(color){

        series.areaStyle = {
          normal: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                  offset: 0,
                  color: color + 'FF'
              },{
                  offset: 0.5,
                  color: color + '7F'
              }, {
                  offset: 1,
                  color: color + '00'
              }])
          }
        }
      }
      return series
    },
    startRotate() {
      // console.log(this.scale)
      let tagsNum = this.hots.tags.length
      this.hots.RADIUS = Math.min(parseInt(this.style.width), parseInt(this.style.height)) / 2
      var tags = [];
      var colors = ["#e86e6e", "#c8b566", "#6ee8bf", "#7e6654", "#6eafe8"];
      for (var i = 0; i < this.hots.tags.length; i++) {
        var tag = {};
        let k = -1 + (2 * (i + 1) - 1) / tagsNum;
        let a = Math.acos(k);
        let b = a * Math.sqrt(tagsNum * Math.PI);
        tag = {
          text: this.hots.tags[i],
          x: this.CX + this.hots.RADIUS * Math.sin(a) * Math.cos(b),
          y: this.CY +  this.hots.RADIUS * Math.sin(a) * Math.sin(b), 
          z: this.hots.RADIUS * Math.cos(a)
        };
        tag.size = 24;
        tags.push(tag);
      }
      this.hots.tags = tags;
      this.hots.playtimeout = setInterval(() => {
        this.rotateX(this.hots.speedX);
        this.rotateY(this.hots.speedY);
      }, 60);
    },
    rotateX(angleX) {
      this.hots.playtime++;
      var cos = Math.cos(angleX);
      var sin = Math.sin(0);
      for (let tag of this.hots.tags) {
        var y1 = (tag.y - this.CY) * cos - tag.z * sin + this.CY;
        var z1 = tag.z * cos + (tag.y - this.CY) * sin;
        tag.y = y1;
        tag.z = z1;
      }
    },
    rotateY(angleY) {
      var cos = Math.cos(angleY);
      var sin = Math.sin(angleY);
      for (let tag of this.hots.tags) {
        var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
        var z1 = tag.z * cos + (tag.x - this.CX) * sin;
        tag.x = x1;
        tag.z = z1;
      }
    }
  }
};
</script>
<style lang="less">
.wordediter {
  border: 0;
  outline: 0;
  width: 94%;
  position: relative;
  height: calc(100% - 10px);
  padding: 0;
  margin: 5px auto;
  display: block;
  box-sizing: border-box;
}
.removecomponents {
  position: absolute;
  right: 0px;
  top: 0px;
  font-size: 28px;
  display: none;
  color: #f56c6c;
  z-index: 9999;
  cursor: pointer;
}
.active {
  z-index: 999 !important;
}
.active .removecomponents {
  display: block;
}
.sys-tabel tr {
  font-size: 14px;
}
.sys-tabel td {
  font-size: 12px;
}
.sys-tabel,
.el-table__expanded-cell {
  background: transparent;
}
.sys-tabel th,
.sys-tabel tr {
  background: transparent;
  padding: 0px 0;
}
.sys-tabel td,
.sys-tabel th.is-leaf {
  border-bottom: 0;
}
.el-table--enable-row-hover .el-table__body tr:hover > td {
  background: transparent;
}
.sys-tabel::before {
  height: 0;
}
.el-table--scrollable-y .el-table__body-wrapper {
  overflow: hidden;
}
.sys-tabel .el-table__body-wrapper::-webkit-scrollbar {
  width: 5px;
  background-color: rgba(0, 0, 0, 0);
}

.sys-tabel .el-table__body-wrapper::-webkit-scrollbar-thumb {
  border-radius: 5px;
  -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.3);
  background-color: #555;
}
</style>
